/*
 * @Author: czy
 * @Date: 2021-05-28 14:30:04
 * @LastEditTime: 2021-07-13 21:12:04
 */
#include "vsprintf.h"

#include "sys/system.h"
#include "sys/type.h"

static unsigned int pMemStart = -1;
static unsigned int pMemSize = -1;
static unsigned int pMemUsed = 0;
extern unsigned int _end;

/**
 * @description: Memory Test.
 * @param start		Detection starting point.
 * @param grainSize	Step.
 */
static void memTest(unsigned int start, unsigned int grainSize)
{
	unsigned int _end_addr = (unsigned int)&_end;
	int16 data;
	int16 *pointer = (int16 *)start;
	int flag = 0;
	int num = 0;
	start = start > 0x100000 ? start : 0x100000;
	grainSize = grainSize > 0x1000 ? grainSize : 0x1000;
	while (1)
	{
		data = *pointer;
		*pointer = (int16)0xAA55;
		if ((int16)0xAA55 != *pointer)
		{
			break;
		}
		*pointer = (int16)0x55AA;
		if ((int16)0x55AA != *pointer)
		{
			break;
		}
		*pointer = data;
		if (flag == 0)
		{
			pointer += (grainSize - 2);
			flag = 1;
		}
		else
		{
			pointer += 2;
			flag = 0;
			num++;
		}
	}
	pMemStart = start;
	pMemSize = start + num * grainSize;
	if (pMemStart <= _end_addr)
	{
		pMemSize -= _end_addr - pMemStart;
		pMemStart = _end_addr;
	}
	return;
}

/**
 * @description: Get memory start address.
 * @return Memory start address.
 */
unsigned int getMemStart(void)
{
	if ((int)pMemStart < 0)
	{
		memTest(0x100000, 0x1000);
	}
	return pMemStart;
}

/**
 * @description: Get memory size.
 * @return Memory size.
 */
unsigned int getMemSize(void)
{
	if ((int)pMemSize < 0)
	{
		memTest(0x100000, 0x1000);
	}
	return pMemSize * 0.9;
}